package com.hystrix.service;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class UserService {

    @Autowired
    private RestTemplate restTemplate;

    private static final String REMINDER_RESULT = "页面飞去太平洋，正在乘坐辽宁舰返回......";

    private static final Logger log = LoggerFactory.getLogger(UserService.class);

    /**
     * execution.isolation.strategy：隔离策略
     *      -THREAD:线程隔离，在独立的线程上执行，并且它的并发限制受线程中的线程数量的限制。
     *      -SEMAPHORE:信号隔离，在调用线程上执行，并且它的并发限制受信号量的计数的限制。
     *
     * execution.isolation.thread.timeoutInMilliseconds：表示请求线程总超时时间，
     *       如果超过这个设置的时间hystrix就会调用fallback方法。value的参数为毫秒，默认值为1000ms。
     *
     * execution.timeout.enabled：这个超时开关表示，当超时后是否触发fallback方法，默认为true
     *
     * circuitBreaker.requestVolumeThreshold：熔断器在整个统计时间内是否开启的阀值，每个熔断器默认维护10个bucket,每秒一个bucket,每个bucket记录成功,失败,超时,拒绝的状态，该阈值默认20次。也就是一个统计窗口时间内（10秒钟）至少请求20次，熔断器才启动。
     *
     * circuitBreaker.errorThresholdPercentage：熔断器错误阈值，默认为50%。
     *
     * coreSize：执行命令线程池的核心线程数，默认10。
     *
     * maxQueueSize：表示线程池的最大队列大小，-1：使用SynchronousQueue,其他使用：LinkedBlockingQueue
     *
     * queueSizeRejectionThreshold：表示等待队列超过阈值后开始拒绝线程请求，默认值为5，如果maxQueueSize为1，则该属性失效。
     *
     * keepAliveTimeMinutes：如果线程池的最大值大于线程池的大小，那么这个配置用于回收多久没被使用的线程
     *
     * metrics.rollingStats.timeInMilliseconds：设置滚动时间窗的长度
     *
     * metrics.rollingStats.numBuckets：设置滚动时间窗被划分成桶的数量
     * */
    @HystrixCommand(fallbackMethod = "helloFallback",
            commandProperties = {   @HystrixProperty(name = "execution.isolation.strategy",value = "THREAD"),
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "4000"),
                    @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
                    @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "40")},
            threadPoolProperties = {   @HystrixProperty(name = "coreSize", value = "1"),
                    @HystrixProperty(name = "maxQueueSize", value = "10"),
                    @HystrixProperty(name = "keepAliveTimeMinutes", value = "1000"),
                    @HystrixProperty(name = "queueSizeRejectionThreshold", value = "8"),
                    @HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "12"),
                    @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "1440")})
    public String getBaseInfo(){
        String result = restTemplate.getForObject("http://provider-server",String.class);
        return result;
    }

    private String helloFallback(){
        return REMINDER_RESULT;
    }


}
